package com.bjpowernode.queue;

import java.util.Arrays;

/**
 * @ClassName LoopQueue
 * @Description TODO 环状队列：front 指向队列的第一个元素，初始化为0
 *                            rear 指向队列最后一个元素的下一个索引处，初始化为0
 *                   分析说明：
 *                      1、尾索引的下一个取模为头索引时表示队列满，即原队列容量空出一个作为固定约定
 *                            (rear+1)%maxsize = front
*                          举个例子：该数组最大容量为 7，当存储了6个元素的时候，最后一个元素的下标是5，那么此时
 *                                  rear对应的值就是 5+1 = 6，也就是指向了该数组的最后一个索引
 *                                  而此时front=0，则根据上述判断队列满的公式，（6+1）%7 = 0，刚好队列满，且只存储了maxsize-1个元素
*                       2、rear == front 时，队列为空
 *                      3、队列中有效元素的个数： (rear + maxsize - front)%maxsize
 * @date 2021/9/16 16:00
 * @Author ZY
 */
public class LoopQueue {
    private int rear = 0;
    private int front = 0;
    private int maxsize = 0;
    private int[] dataStore;

    public LoopQueue(int maxsize) {
        this.maxsize = maxsize;
        dataStore = new int[maxsize];
    }

    @Override
    public String toString() {
        String ret = "";
        ret += "[";
        if (rear > front){
            for (int i = front;i<rear;i++){
                ret = ret + dataStore[i] + ",";
            }
        }else if (rear < front){
            for (int i = front;i<maxsize;i++){
                ret = ret + dataStore[i] + ",";
            }
            for (int i = 0;i<rear;i++){
                ret = ret + dataStore[i] + ",";
            }
        }else {
            for (int i = 0; i < maxsize; i++) {
                ret = ret + dataStore[i] + ",";
            }
        }

        if (ret.endsWith(",")){
            ret = ret.substring(0,ret.length()-1);
        }
        ret += "]";
        return ret;
    }

    // 判断队列是否满
    public boolean isFull(){
        if ((rear + 1)%maxsize == front){
            return true;
        }else {
            return false;
        }
    }
    // 判断队列是否为空
    public boolean isEmpty(){
        if (rear == front){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 添加元素
     * @param element 预添加的元素
     */
    public void add(int element){
        if (isFull()){
            System.out.println("队列已满，添加失败~");
            return;
        }
        dataStore[rear] = element;
        rear++;
        if (rear >= maxsize){
            rear %= maxsize;
        }
    }

    /**
     * 取得元素
     * @return 取得的元素
     */
    public int get() {
        if (isEmpty()){
            throw new RuntimeException("队列为空！~");
        }
        int ret = dataStore[front];
        dataStore[front] = 0;
        front++;
        if (front >= maxsize){
            front %= maxsize;
        }
        return ret;
    }
}
